package com.homwee.factory.util;

import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.UUID;
//import com.changhong.setting.R;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
//zcj 2018-10-31 import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSocket;
//zcj 2018-10-31 import android.bluetooth.BluetoothUuid;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.util.Log;

public class BTManager {
	private static BTManager instance;
	private final String TAG = "Setting";
	private Context mContext;
	public static ArrayList<String> BTData = new ArrayList<>();
	public BluetoothAdapter mBTAdapter;
	private Handler mHandler;
	private BluetoothDevice mConnectDevice;
	public BluetoothDevice mDisConnectDevice;
	public int type;
	public String mPairingKey;

	public final static int MSG_BT_DEVICE_FOUND = 100;
	public final static int MSG_BT_DISCOVERY_STARTED = 101;
	public final static int MSG_BT_DISCOVERY_FINISHED = 102;
	public final static int MSG_BT_STATE_OFF = 103;
	public final static int MSG_BT_STATE_TURNING_OFF = 104;
	public final static int MSG_BT_STATE_ON = 105;
	public final static int MSG_BT_STATE_TURNING_ON = 106;
	public final static int MSG_BT_STATE_BONDED = 107;
	public final static int MSG_BT_STATE_BONDING = 108;
	public final static int MSG_BT_STATE_BONDNONE = 109;
	public final static int MSG_BT_STATE_BONDSUCCESS = 200;
	public final static int MSG_BT_STATE_CONNECTED = 201;
	public final static int MSG_BT_STATE_PAIRING_PASSKEYORPIN = 202;
	public final static int MSG_BT_STATE_DISCONNECTED = 203;
	public final static int MSG_BT_STATE_PAIRING_CONFIRM = 204;
	public final static int MSG_BT_STATE_PAIRING_VARIANT_PIN = 205;
	public final static int MSG_BT_STATE_BOND_ERROR = 206;
	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			Log.d(TAG, "action =" + action);
			// found devices
			if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				Log.d(TAG, "BluetoothDevice.ACTION_FOUND");
				// get devices from intent
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

				if (device != null) {
					Message msg = mHandler.obtainMessage(MSG_BT_DEVICE_FOUND,
							device);
					mHandler.sendMessage(msg);
				}

				Log.d(TAG, "=======device==name=========" + device.getName());

			} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
				Log.d(TAG, "BluetoothAdapter.ACTION_STATE_CHANGED:"
						+ getBluetoothStatus());
				int btStatus = getBluetoothStatus();
				switch (btStatus) {
				case BluetoothAdapter.STATE_TURNING_OFF:
					mHandler.sendEmptyMessage(MSG_BT_STATE_TURNING_OFF);
					break;
				case BluetoothAdapter.STATE_OFF:
					mHandler.sendEmptyMessage(MSG_BT_STATE_OFF);
					break;
				case BluetoothAdapter.STATE_TURNING_ON:
					mHandler.sendEmptyMessage(MSG_BT_STATE_TURNING_ON);
					break;
				case BluetoothAdapter.STATE_ON:
					mHandler.sendEmptyMessage(MSG_BT_STATE_ON);
					break;
				}
			} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
				Log.d(TAG, "BluetoothAdapter.ACTION_DISCOVERY_STARTED:"
						+ getBluetoothStatus());

				mHandler.sendEmptyMessage(MSG_BT_DISCOVERY_STARTED);

			} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
					.equals(action)) {
				Log.d(TAG, "BluetoothAdapter.ACTION_DISCOVERY_FINISHED:"
						+ getBluetoothStatus());
				mHandler.sendEmptyMessage(MSG_BT_DISCOVERY_FINISHED);
			} else if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
				Log.d(TAG, "BluetoothDevice.ACTION_PAIRING_REQUEST");

				type = intent.getIntExtra(
						BluetoothDevice.EXTRA_PAIRING_VARIANT,
						BluetoothDevice.ERROR);
				Log.d(TAG, "pairing key type = " + type);
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				switch (type) {
				//zcj 2018-10-31 case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
				//zcj 2018-10-31 case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
				case 1:
					Log.d(TAG,
							"====keyboard======PAIRING=======PIN==============");
					int pairingKey = intent.getIntExtra(
							BluetoothDevice.EXTRA_PAIRING_KEY,
							BluetoothDevice.ERROR);
					if (pairingKey == BluetoothDevice.ERROR) {
						Log.e(TAG,
								"Invalid Confirmation Passkey or PIN received, not showing any dialog");
						return;
					}
					// if (type ==
					// BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
					// mPairingKey = String.format("%06d", pairingKey);
					// } else {
					// mPairingKey = String.format("%04d", pairingKey);
					// }

					Message msg = mHandler.obtainMessage(
							MSG_BT_STATE_PAIRING_PASSKEYORPIN, type,
							pairingKey, device);
					mHandler.sendMessage(msg);
					break;
				case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
					Log.d(TAG,
							"=======phone=======PAIRING=======PIN==============");
					int passkey = intent.getIntExtra(
							BluetoothDevice.EXTRA_PAIRING_KEY,
							BluetoothDevice.ERROR);
					if (passkey == BluetoothDevice.ERROR) {
						Log.e(TAG,
								"Invalid Confirmation Passkey received, not showing any dialog");
						return;
					}
					// mPairingKey = String.format(Locale.US, "%06d", passkey);

					Message msg1 = mHandler
							.obtainMessage(MSG_BT_STATE_PAIRING_CONFIRM, type,
									passkey, device);
					mHandler.sendMessage(msg1);

					break;
				case BluetoothDevice.PAIRING_VARIANT_PIN:
					Log.d(TAG,
							"=======PAIRING=======VARIANT=======PIN==============");
					Message msg2 = mHandler.obtainMessage(
							MSG_BT_STATE_PAIRING_VARIANT_PIN, type, 0, device);
					mHandler.sendMessage(msg2);

					break;
				default:
					Log.d(TAG, "==========PAIRING=====no==PIN==============");
					setPasskeyComfirm(device, true);
					cancelUserInputPairing(device);
					break;
				}

			} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
				Log.d(TAG, "BluetoothDevice.ACTION_BOND_STATE_CHANGED ");

				int state = intent.getIntExtra(
						BluetoothDevice.EXTRA_BOND_STATE,
						BluetoothDevice.BOND_NONE);
				mConnectDevice = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

				switch (state) {
				case BluetoothDevice.BOND_BONDING:
					Log.d(TAG, "BluetoothDevice.BOND_BONDING ");
					Log.d(TAG, "BluetoothDevice.BOND_BONDING== "
							+ mConnectDevice.getName());
					Message msg = mHandler.obtainMessage(MSG_BT_STATE_BONDING,
							mConnectDevice);
					mHandler.sendMessage(msg);
					// mHandler.sendEmptyMessage(MSG_BT_STATE_BONDING);

					break;
				case BluetoothDevice.BOND_BONDED:
					Log.d(TAG, "BluetoothDevice.BOND_BONDED== "
							+ mConnectDevice.getName());
					Message msg1 = mHandler.obtainMessage(MSG_BT_STATE_BONDED,
							mConnectDevice);
					mHandler.sendMessage(msg1);
					// mHandler.sendEmptyMessage(MSG_BT_STATE_BONDED);

					if (mConnectDevice.getBluetoothClass().getDeviceClass() != 524) {

						onBluetoothConnect(mConnectDevice);
					}

					break;

				case BluetoothDevice.BOND_NONE:

				/*//zcj 2018-10-31	int reason = intent
							.getIntExtra(BluetoothDevice.EXTRA_REASON,
									BluetoothDevice.ERROR);*/
					int reason=0;
					Log.d(TAG,
							"BluetoothDevice.BOND_NONE == "
									+ mConnectDevice.getName());
					Message msg3 = mHandler.obtainMessage(
							MSG_BT_STATE_BONDNONE, reason, 0, mConnectDevice);
					mHandler.sendMessage(msg3);
					// mHandler.sendEmptyMessage(MSG_BT_STATE_BONDNONE);

					showUnbondMessage(mContext, mConnectDevice.getName(),
							reason);

					break;

				}
			} else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				Log.d(TAG,
						"==============BluetoothDevice.ACTION_ACL_CONNECTED================"
								+ device.getName());
				mHandler.sendEmptyMessage(MSG_BT_STATE_CONNECTED);
			} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				Log.d(TAG,
						"==============BluetoothDevice.ACTION_ACL_DISCONNECTED================"
								+ device.getName());
				mDisConnectDevice = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				Log.d(TAG, "==============mConnectDevice==============="
						+ mDisConnectDevice.getName());
				mHandler.sendEmptyMessage(MSG_BT_STATE_DISCONNECTED);
			} else if (BluetoothDevice.ACTION_UUID.equals(action)) {
				Log.d(TAG,
						"==============BluetoothDevice.ACTION_UUID================");
			}
		}
	};

	private void showUnbondMessage(Context context, String name, int reason) {
		String errorMsg;
		switch (reason) {
		/*//zcj 2018-10-31 case BluetoothDevice.UNBOND_REASON_AUTH_FAILED:
			errorMsg ="pairing error!";// mContext.getString(R.string.bluetooth_pairing_pin_error_message);

			Log.w(TAG, "showUnbondMessage: reason: " + reason);
			mHandler.sendEmptyMessage(MSG_BT_STATE_BOND_ERROR);
			break;*/
		default:
			Log.w(TAG,
					"showUnbondMessage: Not displaying any message for reason: "
							+ reason);
			break;
		}
	}

	private void connect(BluetoothDevice device) {
		final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
		UUID uuid = UUID.fromString(SPP_UUID);

		try {
			BluetoothSocket socket = device
					.createRfcommSocketToServiceRecord(uuid);
			socket.connect();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private BTManager(Context context) {
		mContext = context;
		mBTAdapter = BluetoothAdapter.getDefaultAdapter();

		Log.d(TAG, "mBTAdapter =" + mBTAdapter);
	}

	public static BTManager getInstance(Context context) {
		if (instance == null) {
			instance = new BTManager(context);
		}
		return instance;
	}

	public void setHandler(Handler handler) {
		mHandler = handler;
	}

	public void registerBTReceiver() {
		IntentFilter filter = new IntentFilter();
		filter.addAction(BluetoothDevice.ACTION_FOUND);
		filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
		filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
		filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
		filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
		filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
		filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
		filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
		mContext.registerReceiver(mReceiver, filter);

	}

	public void unregisterBTReceiver() {
		mContext.unregisterReceiver(mReceiver);
	}

	public void setBTStatus() {
		if (null == mBTAdapter) {
			// Toast.makeText(mContext, "No BT devices.",
			// Toast.LENGTH_SHORT).show();
			return;
		}
		switch (getBluetoothStatus()) {
		case BluetoothAdapter.STATE_ON:
		case BluetoothAdapter.STATE_TURNING_ON:
			mBTAdapter.disable();
			break;
		case BluetoothAdapter.STATE_OFF:
		case BluetoothAdapter.STATE_TURNING_OFF:
			mBTAdapter.enable();
			break;
		}

	}

	public BluetoothDevice getRemoteBtDevice(String address) {
		return mBTAdapter.getRemoteDevice(address);
	}

	public String getLocalDeviceName() {
		return mBTAdapter.getName();
	}

	public void findBT() {
		if (getBluetoothStatus() == BluetoothAdapter.STATE_ON) {
			mBTAdapter.startDiscovery();
		}
	}

	public int getBluetoothStatus() {
		return mBTAdapter.getState();
	}

	public void setBTNeverTimeout() {
		/*//zcj 2018-10-31 mBTAdapter.setScanMode(
				BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, 0);*/
	}

	public boolean startPairing(BluetoothDevice btDevice) {

		if (btDevice.createBond()) {
			return true;
		}
		return false;
	}

	public boolean cancelUserInputPairing(BluetoothDevice btDevice) {
		//zcj 2018-10-31return btDevice.cancelPairingUserInput();
		return false;
	}

	public boolean setPairPin(BluetoothDevice btDevice, String pin) {

		return btDevice.setPin(pin.getBytes());
	}

	@SuppressLint({ "NewApi", "NewApi", "NewApi" })
	public void onBluetoothConnect(BluetoothDevice device) {
		mConnectDevice = device;
		if (device == null) {
			return;
		}
		if (device.getName() != null
				&& (device.getName().equalsIgnoreCase("RBD800VC")
						|| device.getName().equalsIgnoreCase("CH BT RC") || device
						.getName().equalsIgnoreCase("RC1026"))) {

			Log.d(TAG, "device.getName()===============" + device.getName());
		} else {

			int deviceMajorClass = device.getBluetoothClass()
					.getMajorDeviceClass();
			int deviceClass = device.getBluetoothClass().getDeviceClass();
			ParcelUuid[] uuids = device.getUuids();
			Log.d(TAG, "deviceClass =" + deviceClass);
			Log.d(TAG, "deviceMajorClass =" + deviceMajorClass);
			if (uuids != null) {

				for (ParcelUuid uuid : uuids) {

					Log.d(TAG, "uuid============" + uuid);
				}

				/*//zcj 2018-10-31Log.d(TAG, "BluetoothUuid.audio========"
						+ BluetoothUuid.AudioSource);
				Log.d(TAG, "BluetoothUuid.hid========" + BluetoothUuid.Hid);
				Log.d(TAG, "BluetoothUuid.hogp========" + BluetoothUuid.Hogp);
				Log.d(TAG, "BluetoothUuid.hs========"
						+ BluetoothUuid.Handsfree_AG);
				Log.d(TAG, "BluetoothUuid.hsp========" + BluetoothUuid.HSP_AG);
				// if(deviceClass ==
				// BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER)
				if (BluetoothUuid.isUuidPresent(uuids,
						BluetoothUuid.AudioSource)
						|| BluetoothUuid.isUuidPresent(uuids,
								BluetoothUuid.AudioSink)) {

					Log.d(TAG, "A2DP================");

					mBTAdapter.getProfileProxy(mContext, mA2dpProfileListener,
							BluetoothProfile.A2DP);
				}
				// if(deviceMajorClass ==
				// BluetoothClass.Device.Major.PERIPHERAL){
				if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid)
						|| BluetoothUuid.isUuidPresent(uuids,
								BluetoothUuid.Hogp)) {

					Log.d(TAG, "INPUT_DEVICE================");
					mBTAdapter.getProfileProxy(mContext,
							mInputDeviceProfileListener,
							BluetoothProfile.INPUT_DEVICE);
				}
				// if(deviceMajorClass ==
				// BluetoothClass.Device.AUDIO_VIDEO_UNCATEGORIZED){
				if (BluetoothUuid.isUuidPresent(uuids,
						BluetoothUuid.Handsfree_AG)
						|| BluetoothUuid.isUuidPresent(uuids,
								BluetoothUuid.HSP_AG)) {

					Log.d(TAG, "HEADSET================");
					mBTAdapter.getProfileProxy(mContext,
							mHeadSetProfileListener, BluetoothProfile.HEADSET);
				}*/

			}
			if (deviceMajorClass == BluetoothClass.Device.PHONE_UNCATEGORIZED) {

			}
		}
	}

	public boolean setPasskeyComfirm(BluetoothDevice btDevice, boolean confirm) {
		return btDevice.setPairingConfirmation(confirm);
	}

	BluetoothHeadset mBluetoothHeadset;
	//zcj 2018-10-31 BluetoothInputDevice mBluetoothInput;
	BluetoothA2dp mBluetoothA2dp;

	private BluetoothProfile.ServiceListener mA2dpProfileListener = new BluetoothProfile.ServiceListener() {

		@Override
		public void onServiceDisconnected(int profile) {
			if (profile == BluetoothProfile.A2DP) {
				Log.d(TAG, "disconnect to A2DP !!!");
				// mBluetoothA2dp = null;
			}
		}

		@SuppressLint({ "NewApi", "NewApi" })
		@Override
		public void onServiceConnected(int profile, BluetoothProfile proxy) {
			mBluetoothA2dp = (BluetoothA2dp) proxy;
			if (profile == BluetoothProfile.A2DP) {
				try {
					Log.d(TAG, "connect to A2dp !!!");
					//zcj 2018-10-31 mBluetoothA2dp.connect(mConnectDevice);
					Log.d(TAG,
							"a2dp getConnectionState : "
									+ mBluetoothA2dp
											.getConnectionState(mConnectDevice));
					if (mBluetoothA2dp.getConnectionState(mConnectDevice) == 2) {

						mHandler.sendEmptyMessage(MSG_BT_STATE_CONNECTED);
					}
					// get connected devices
					List<BluetoothDevice> mDevices = proxy
							.getConnectedDevices();
					if (mDevices != null && mDevices.size() > 0) {
						for (BluetoothDevice device : mDevices) {
							Log.d(TAG, "a2dpdevice name:" + device.getName());
						}
					}
					// get connected devices
				} catch (Exception e) {
					Log.d(TAG, "connect to a2dp failed!!!");
					// mHandler.sendEmptyMessage(MSG_BT_STATE_DISCONNECTED_A2DP);
					mBTAdapter.closeProfileProxy(BluetoothProfile.A2DP,
							mBluetoothA2dp);
					e.printStackTrace();
				}
			}
			mBTAdapter.closeProfileProxy(profile, proxy);
		}
	};

	private BluetoothProfile.ServiceListener mHeadSetProfileListener = new BluetoothProfile.ServiceListener() {

		@Override
		public void onServiceDisconnected(int profile) {
			if (profile == BluetoothProfile.HEADSET) {
				Log.d(TAG, "disconnect to HEADSET !!!");
				mBluetoothHeadset = null;
			}
		}

		@SuppressLint({ "NewApi", "NewApi" })
		@Override
		public void onServiceConnected(int profile, BluetoothProfile proxy) {
			mBluetoothHeadset = (BluetoothHeadset) proxy;
			if (profile == BluetoothProfile.HEADSET) {
				/*//zcj 2018-10-31 try {
					Log.d(TAG, "connect to HEADSET !!!");
					mBluetoothHeadset.connect(mConnectDevice);
					Log.d(TAG,
							"headset getConnectionState : "
									+ mBluetoothInput
											.getConnectionState(mConnectDevice));
					if (mBluetoothHeadset.getConnectionState(mConnectDevice) == 2) {
						mHandler.sendEmptyMessage(MSG_BT_STATE_CONNECTED);
					}

					// get connected devices
					List<BluetoothDevice> mDevices = proxy
							.getConnectedDevices();
					if (mDevices != null && mDevices.size() > 0) {
						for (BluetoothDevice device : mDevices) {
							Log.d(TAG, "headsetdevice name:" + device.getName());
						}
					}
					// get connected devices
				} catch (Exception e) {
					Log.d(TAG, "connect to Headset failed!!!");
					mBTAdapter.closeProfileProxy(BluetoothProfile.HEADSET,
							mBluetoothHeadset);
					e.printStackTrace();
				}*/
			}
			mBTAdapter.closeProfileProxy(profile, proxy);
		}
	};

	private BluetoothProfile.ServiceListener mInputDeviceProfileListener = new BluetoothProfile.ServiceListener() {
		@SuppressLint("NewApi")
		public void onServiceConnected(int profile, BluetoothProfile proxy) {
			/*//zcj 2018-10-31 if (profile == BluetoothProfile.INPUT_DEVICE) {
				Log.d(TAG, "connect to input device.");
				mBluetoothInput = (BluetoothInputDevice) proxy;
				mBluetoothInput.connect(mConnectDevice);
				Log.d(TAG,
						"input getConnectionState : "
								+ mBluetoothInput
										.getConnectionState(mConnectDevice));
				if (mBluetoothInput.getConnectionState(mConnectDevice) == 2) {

					mHandler.sendEmptyMessage(MSG_BT_STATE_CONNECTED);
				}

				// get connected devices
				List<BluetoothDevice> mDevices = proxy.getConnectedDevices();
				if (mDevices != null && mDevices.size() > 0) {
					for (BluetoothDevice device : mDevices) {
						Log.d(TAG, "inputdevice name:" + device.getName());
					}
				}
				// get connected devices
			}*/
			mBTAdapter.closeProfileProxy(profile, proxy);
		}

		public void onServiceDisconnected(int profile) {
			/*//zcj 2018-10-31 if (profile == BluetoothProfile.INPUT_DEVICE) {
				Log.d(TAG, "disconnect to INPUTDEVICE !!!");
				mBluetoothInput = null;
			}*/
		}
	};

	// private BluetoothProfile.ServiceListener mHidDeviceProfileListener = new
	// BluetoothProfile.ServiceListener() {
	//
	// public void onServiceDisconnected(int profile) {
	// // TODO Auto-generated method stub
	//
	// }
	//
	// public void onServiceConnected(int profile, BluetoothProfile proxy) {
	// // TODO Auto-generated method stub
	// Log.d(TAG, "connect to input device.");
	// mBluetoothInput = (BluetoothInputDevice) proxy;
	// Log.d(TAG, "getConnectionState : "
	// +mBluetoothInput.getConnectionState(mConnectDevice));
	// mHandler.sendEmptyMessage(MSG_BT_STATE_CONNECTED);
	// mBluetoothInput.connect(mConnectDevice);
	// }
	// };

}
